import prefuse
import java
import MatrixIO
from Matrix import *
import javax.swing.BorderFactory as BorderFactory;
from prefuse.visual import *
import java.lang.Math as Math
import jarray

class PyRun(java.lang.Runnable):
	obj = None
	L=None
	def __init__(self,obj,L):
		self.L=L
		self.obj=obj
	def run(self):
		for l in self.L:
			self.obj.run(l)

# now I need to clean this up.. make it a module.. and make it fast
class ColorMap(java.lang.Object):
	COLOUR_MAX_VALUE = 255;
	maxAbsValue=None;
	minVal=None;
	tabColor = [0,60,102,153,204,COLOUR_MAX_VALUE];
	TAB_LIMIT_VALUE = [25,76,123,179,230,COLOUR_MAX_VALUE];
	carray = []
	def getColor(self,value):
		if (self.maxAbsValue == None):
			self.maxAbsValue = 2.0;
		dValeur = java.lang.Double(value);
		colorIndex = (self.COLOUR_MAX_VALUE * Math.abs(dValeur) / self.maxAbsValue);
		if (colorIndex > self.COLOUR_MAX_VALUE):
			colorIndex = self.COLOUR_MAX_VALUE;
		for i in xrange(0,len(self.TAB_LIMIT_VALUE)):
			if (colorIndex <= self.TAB_LIMIT_VALUE[i]):
				colorIndex = self.tabColor[i];
				break;
		if (dValeur >= 0):
			return java.awt.Color(0, colorIndex, 0).getRGB();
		return java.awt.Color(colorIndex, 0, 0).getRGB();

####end class
class VerticalLineLayout(prefuse.action.layout.Layout):
        m_maxHeight = 800;
	m_vis=None
	scale=1
	cmap=ColorMap()
	def __init__(self,maxHeight,viz):
		self.m_maxHeight = maxHeight;
		self.m_vis = viz
		self.scale=1;
	def run(self,frac):
            w = 0; h = 0;
            iter = self.m_vis.items();
            while iter.hasNext():
                item = iter.next();
                item.setSize(1.0);
                h = h + item.getBounds().getHeight();
		#scale = 1.0;
		if h > self.m_maxHeight: 
			scale = self.m_maxHeight/h;
	    d = self.m_vis.getDisplay(0);
	    ins = d.getInsets();
###           // second pass
            hlast1 = hlast2 = h = ins.top;
            ih=0; y=0; x=ins.left;
	    iter = self.m_vis.items();
	    while ( iter.hasNext() ):
                item = iter.next();
                item.setSize(self.scale); item.setEndSize(self.scale);
		if item.isInGroup("genes"):
			b = item.getBounds();
			w = java.lang.Math.max(w, b.getWidth());
			ih = 10;b.getHeight();
			x=ins.left
			y = hlast1+(ih/2);
			self.setX(item, None, x);
			self.setY(item, None, y);
			h = hlast1 + ih;
			hlast1=h;
		else:
			# I need to draw the whole line...
			# hack vizual item??
			b = item.getBounds();
			w = java.lang.Math.max(w, b.getWidth());
			ih = b.getHeight();
			x=ins.left
			y = hlast1 + (ih/2);
			x=x+float(item.getSourceTuple().getString("x"))
			y=y+float(item.getSourceTuple().getString("y"))
#			item.setFillColor(java.lang.Integer(self.cmap.getColor(item.getSourceTuple().getString("data"))))
#			item.setShape(prefuse.Constants.SHAPE_RECTANGLE)
			# can I rescale these?
			self.setX(item, None, x);
			self.setY(item, None, y);
			#item.setSize(1)

		#d.setSize(Math.round(2*scale*w + ins.left + ins.right),Math.round(h + ins.bottom));	

class GeneExpressionFactory(prefuse.render.DefaultRendererFactory):
	srend = prefuse.render.ShapeRenderer()
	lrend = prefuse.render.LabelRenderer("gene");

	def __init__(self):
		self.lrend.setTextField("gene");
		self.lrend.setHorizontalPadding(1)
		self.lrend.setVerticalPadding(1)
		self.lrend.setHorizontalAlignment(prefuse.Constants.LEFT);
		self.srend.setBaseSize(10) 
	def getRenderer(self,item):
		#print item
		if item.isInGroup("genes"):
			return self.lrend;
		else:
			return self.srend



class PrefuseHeatMap(javax.swing.JComponent):
	display = None
	d=None
	viz=None
	#tblList = []
	#geneList = prefuse.data.Table()
	
	def __init__(self,d):
		self.d = d
		dlabels = d.rowNames
		explabels = d.columnNames[1:len(d.columnNames)]
		[r,c]=size(d)
		G = prefuse.data.Table()
		G.addColumn("gene",java.lang.String,"g")
		for j in dlabels:
			x=G.addRow()
			G.setString(x,"gene",j)
		T=[]
		xlast=0
		ylast=0
		viz = prefuse.Visualization()
		disp = prefuse.Display(viz)
		init = prefuse.action.ActionList();
		init.add(VerticalLineLayout(800,viz))
		shaper=prefuse.action.ActionList()
		cb = prefuse.util.ColorLib.color(java.awt.Color.black)
		cmap =prefuse.util.ColorLib().getCoolPalette()
		for j in explabels:
			t = prefuse.data.Table()
			t.addConstantColumn("shape",java.lang.Integer,prefuse.Constants.SHAPE_RECTANGLE)
			t.addColumn("data",java.lang.Double,0.0)
			t.addColumn("x",java.lang.Integer,xlast)
			t.addColumn("y",java.lang.Integer,ylast)
			T+=[t]
			viz.addTable(j, t)
			t = None
			init.add( prefuse.action.assignment.DataShapeAction(j,"shape"));
			x = prefuse.action.assignment.DataColorAction(j,"data",prefuse.Constants.NOMINAL,prefuse.visual.VisualItem.FILLCOLOR,cmap)
			shaper.add(x)
			x = prefuse.action.assignment.ColorAction(j,prefuse.visual.VisualItem.STROKECOLOR,cb)
			shaper.add(x)

		ylast=0
		for i in range(1,r+1):
			xlast=50
			for j in range(1,c+1):
				xr=T[j-1].addRow()
				T[j-1].set(xr,"data",java.lang.Double(d[i,j]))
				T[j-1].set(xr,"x",int(xlast))
				T[j-1].set(xr,"y",int(ylast))
				xlast=xlast+10
			ylast=ylast+10;

		
		viz.addTable("genes",G)
		disp.setSize(10,10)
		disp.setBorder(BorderFactory.createEmptyBorder(10,10,10,5));
		renderF = GeneExpressionFactory()
		viz.setRendererFactory(renderF)
		colors = prefuse.action.assignment.ColorAction("genes",prefuse.visual.VisualItem.TEXTCOLOR)
		colors.setDefaultColor(prefuse.util.ColorLib.color(java.awt.Color.black))
	
		init.add(colors)
		init.add(prefuse.action.RepaintAction())
		viz.putAction('init',init)
		viz.putAction('shape',shaper)
		zoom = prefuse.controls.ZoomControl();
		disp.addControlListener(zoom)
		disp.addControlListener(prefuse.controls.PanControl())
		disp.addControlListener(prefuse.controls.WheelZoomControl())
		disp.show()
		disp.setHighQuality(False) 
		self.viz = viz
		runner = PyRun(viz,['init','shape'])
		# need to modify these here so display is fast
		javax.swing.SwingUtilities.invokeLater(runner) 

		disp.stopEditing()
		self.display = javax.swing.JScrollPane(disp)

	def getContentPane(self):
		return self.display

# class PyTreeMap():

